package com.attendance.www.hr.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.attendance.www.hr.beans.ReportAttendanceBean;
import com.attendance.www.hr.beans.ReportAttendancePageBean;
import com.attendance.www.hr.beans.ReportAttendanceParam;
import com.attendance.www.hr.beans.RestVacationBean;
import com.attendance.www.hr.dao.mapper.AttendanceReportExtMapper;
import com.attendance.www.hr.dao.mapper.AttendanceReportMapper;
import com.attendance.www.hr.dao.mapper.EmployeeMapper;
import com.attendance.www.hr.dao.mapper.EmployeeSchedulMapper;
import com.attendance.www.hr.dao.mapper.FurloughBalanceMapper;
import com.attendance.www.hr.dao.mapper.ReportAttendanceExtMapper;
import com.attendance.www.hr.dao.mapper.RequestMapper;
import com.attendance.www.hr.dao.mapper.SystemConfigureMapper;
import com.attendance.www.hr.dao.mapper.YearFurloughMapper;
import com.attendance.www.hr.entitys.Employee;
import com.attendance.www.hr.entitys.EmployeeExample;
import com.attendance.www.hr.entitys.EmployeeSchedul;
import com.attendance.www.hr.entitys.EmployeeSchedulExample;
import com.attendance.www.hr.entitys.FurloughBalance;
import com.attendance.www.hr.entitys.FurloughBalanceExample;
import com.attendance.www.hr.entitys.Request;
import com.attendance.www.hr.entitys.RequestExample;
import com.attendance.www.hr.entitys.SystemConfigure;
import com.attendance.www.hr.entitys.SystemConfigureExample;
import com.attendance.www.hr.entitys.YearFurlough;
import com.attendance.www.hr.entitys.YearFurloughExample;
import com.attendance.www.hr.service.IReportResultService;
import com.attendance.www.hr.service.IReportService;
import com.attendance.www.hr.service.IRestVacationService;
import com.attendance.www.hr.utils.YearFurloughUtils;

@Service
public class ReportResultServiceImpl implements IReportResultService {

	@Resource
	private IReportService reportService;
	@Resource
	private ReportAttendanceExtMapper reportExtDao;
	@Resource
	private IRestVacationService restVacationService;
	@Resource
	private SystemConfigureMapper systemConfigureDao;
	@Resource
	private EmployeeMapper employeeDao;
	@Resource
	private FurloughBalanceMapper furloughBalanceDao;
	@Resource
	private RequestMapper requestDao;
	@Resource
	private AttendanceReportMapper attendanceReporDao;
	@Resource
	private AttendanceReportExtMapper attendanceReporExtDao;
	@Resource
	private YearFurloughMapper yearFurloughDao;
	@Resource
	private EmployeeSchedulMapper employeeSchedulDao;

	private static Logger logger = Logger.getLogger(ReportResultServiceImpl.class);

	/**
	 * 计算报表结果
	 */
	@SuppressWarnings("unlikely-arg-type")
	@Override
	public ReportAttendancePageBean getReportResultInfoList(ReportAttendanceParam paramBean) {

		Calendar calendar2= Calendar.getInstance();
		SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

		Date beginDate = paramBean.getBeginDate();
		Date endDate = paramBean.getEndDate();
		// 格式化结束日期
		endDate = DateUtils.setHours(endDate, 23);
		endDate = DateUtils.setMinutes(endDate, 59);
		endDate = DateUtils.setSeconds(endDate, 59);
		paramBean.setEndDate(endDate);

		// 获取年假可使用时间设置表
		Calendar cal = Calendar.getInstance();
		cal.setTime(paramBean.getEndDate());
		YearFurloughExample yearFurloughExample = new YearFurloughExample();
		yearFurloughExample.createCriteria().andYearEqualTo(cal.get(Calendar.YEAR) - 1)
				.andMonthGreaterThanOrEqualTo(cal.get(Calendar.MONTH) + 1);
		List<YearFurlough> yearFurloughList = yearFurloughDao.selectByExample(yearFurloughExample);

		List<ReportAttendanceBean> reportInfoList = new ArrayList<>();
		int count = 0;

		// 查开始日期
		// List<ReportAttendanceBean> arList1 =
		// attendanceReporExtDao.getIsHasTheDate(beginDate);
		List<ReportAttendanceBean> arList1 = new ArrayList<>();
		// 查结束日期
		// List<ReportAttendanceBean> arList2 =
		// attendanceReporExtDao.getIsHasTheDate(endDate);
		List<ReportAttendanceBean> arList2 = new ArrayList<>();

		if (arList1.size() > 0 && arList2.size() > 0) {// 包含两个日期，查AttendanceReport表
			// if (true) {
			reportInfoList = attendanceReporExtDao.getAttendanceReportList(paramBean);
			count = attendanceReporExtDao.countByParam(paramBean);
			// 分钟转换成天
			for (int i = 0; i < reportInfoList.size(); i++) {
				// ReportAttendanceBean reportAttendanceBean = reportInfoList.get(i);
				// 员工平日加班天数
				// Float value = (float)(Math.round((rab.getOvertimeNomal()/60/8)*100))/100;
				reportInfoList.get(i).setOvertimeNomal(this.minsToDays(reportInfoList.get(i).getOvertimeNomal()));
				// 员工双休日加班天数
				reportInfoList.get(i).setOvertimeWeekend(this.minsToDays(reportInfoList.get(i).getOvertimeWeekend()));
				// 员工节假日加班天数
				reportInfoList.get(i).setOvertimeHoliday(this.minsToDays(reportInfoList.get(i).getOvertimeHoliday()));
				// 员工请年假天数
				reportInfoList.get(i).setRestYearUsed(this.minsToDays(reportInfoList.get(i).getRestYearUsed()));
				// 员工请假调休天数
				reportInfoList.get(i).setRestTuneUsed(this.minsToDays(reportInfoList.get(i).getRestTuneUsed()));
				// 员工请产检假天数
				reportInfoList.get(i).setRestCheckUsed(this.minsToDays(reportInfoList.get(i).getRestCheckUsed()));
				// 员工请哺乳假天数
				reportInfoList.get(i).setRestSuckleUsed(this.minsToDays(reportInfoList.get(i).getRestSuckleUsed()));
				// 员工请病假天数
				reportInfoList.get(i).setRestIllUsed(this.minsToDays(reportInfoList.get(i).getRestIllUsed()));
				// 员工请事假天数
				reportInfoList.get(i).setRestThingUsed(this.minsToDays(reportInfoList.get(i).getRestThingUsed()));

				// 当年考勤统计
				// 员工平日加班天数
				reportInfoList.get(i)
						.setYearOvertimeNomal(this.minsToDays(reportInfoList.get(i).getYearOvertimeNomal()));
				// 员工双休日加班天数
				reportInfoList.get(i)
						.setYearOvertimeWeekend(this.minsToDays(reportInfoList.get(i).getYearOvertimeWeekend()));
				// 员工节假日加班天数
				reportInfoList.get(i)
						.setYearOvertimeHoliday(this.minsToDays(reportInfoList.get(i).getYearOvertimeHoliday()));
				// 可享受年假
				// (float)(Math.round((mins/60/8)*100))/100;
				if (reportInfoList.get(i).getYearRestYearAll() != null) {
					reportInfoList.get(i).setYearRestYearAll(
							(float) Math.round(reportInfoList.get(i).getYearRestYearAll() / 60 / 8));
				}
				// 员工请年假天数
				if (reportInfoList.get(i).getYearRestYearUsed() != null) {
					reportInfoList.get(i).setYearRestYearUsed(
							(float) (Math.round((reportInfoList.get(i).getYearRestYearUsed() / 60 / 8) * 100)) / 100);
				}
				// 剩余年假
				if (reportInfoList.get(i).getRestYearRemain() != null) {
					reportInfoList.get(i).setRestYearRemain(
							(float) (Math.round((reportInfoList.get(i).getRestYearRemain() / 60 / 8) * 100)) / 100);
				}
				// 去年可享受年假天数
				if (reportInfoList.get(i).getYearRestLastYearAll() != null) {
					reportInfoList.get(i).setYearRestLastYearAll(
							(float) Math.round(reportInfoList.get(i).getYearRestLastYearAll() / 60 / 8));
				}
				// 员工请去年年假天数
				if (reportInfoList.get(i).getYearRestLastYearUsed() != null) {
					reportInfoList.get(i).setYearRestLastYearUsed(
							(float) Math.round(reportInfoList.get(i).getYearRestLastYearUsed() / 60 / 8));
				}
				// 员工请假调休天数
				reportInfoList.get(i).setYearRestTuneUsed(this.minsToDays(reportInfoList.get(i).getYearRestTuneUsed()));
				// 剩余调休假
				reportInfoList.get(i)
						.setYearRestTuneRemain(this.minsToDays(reportInfoList.get(i).getYearRestTuneRemain()));
				// 员工请病假天数
				reportInfoList.get(i).setYearRestIllUsed(this.minsToDays(reportInfoList.get(i).getYearRestIllUsed()));
				// 员工请事假天数
				reportInfoList.get(i)
						.setYearRestThingUsed(this.minsToDays(reportInfoList.get(i).getYearRestThingUsed()));
				// 员工请产检假天数
				reportInfoList.get(i)
						.setYearRestCheckUsed(this.minsToDays(reportInfoList.get(i).getYearRestCheckUsed()));
				// 员工请哺乳假天数
				reportInfoList.get(i)
						.setYearRestSuckleUsed(this.minsToDays(reportInfoList.get(i).getYearRestSuckleUsed()));
			}

		} else {

			calendar2= Calendar.getInstance();
			logger.info("执行：getReportAttendanceBaseInfoList开始时间："+dateFormat.format(calendar2.getTime()));
			// 取得报表基本信息
			reportInfoList = reportService.getReportAttendanceBaseInfoList(paramBean);
			calendar2= Calendar.getInstance();
			logger.info("执行：getReportAttendanceBaseInfoList结束时间："+dateFormat.format(calendar2.getTime()));

			// 查询系统配置表
			List<SystemConfigure> systemConfigureList = systemConfigureDao
					.selectByExample(new SystemConfigureExample());

			// 生成出员工id列表
			List<Integer> employeeIds = new ArrayList<Integer>();
			for (ReportAttendanceBean reportAttendanceBean : reportInfoList) {
				employeeIds.add(reportAttendanceBean.getEmployeeId());
			}
			// 查询的人员id集合为空时，提醒
			if (employeeIds.size() == 0) {
				ReportAttendancePageBean reportAttendancePageBean = new ReportAttendancePageBean();
				reportAttendancePageBean.setReportInfoList(reportInfoList);
				reportAttendancePageBean.setPageTotal(count);
				return reportAttendancePageBean;
			}
			// 当年考勤统计
			ReportAttendanceParam paramBeanYear = new ReportAttendanceParam();
			BeanUtils.copyProperties(paramBean, paramBeanYear);

			Calendar cdarBegin = Calendar.getInstance();
			cdarBegin.setTime(paramBeanYear.getBeginDate());
			cdarBegin.set(Calendar.MONTH, 0);
			cdarBegin.set(Calendar.DAY_OF_MONTH, 1);
			cdarBegin.set(Calendar.HOUR_OF_DAY, 0);
			cdarBegin.set(Calendar.MINUTE, 0);
			cdarBegin.set(Calendar.SECOND, 0);
			cdarBegin.set(Calendar.MILLISECOND, 0);

			Calendar cdarEnd = Calendar.getInstance();
			cdarEnd.setTime(cdarBegin.getTime());
			cdarEnd.add(Calendar.YEAR, 1);
			cdarEnd.add(Calendar.MILLISECOND, -1);

			paramBean.setLastBeginDate(cdarBegin.getTime());
			paramBean.setLastEndDate(cdarEnd.getTime());

			// 查询时间的开始，结束时间 TODO
			Calendar yearCalendarEnd = Calendar.getInstance();
			yearCalendarEnd.setTime(beginDate);
			yearCalendarEnd.set(Calendar.MONTH, 0);
			yearCalendarEnd.set(Calendar.DAY_OF_MONTH, 1);
			yearCalendarEnd.set(Calendar.HOUR_OF_DAY, 0);
			yearCalendarEnd.set(Calendar.MINUTE, 0);
			yearCalendarEnd.set(Calendar.SECOND, 0);
			yearCalendarEnd.set(Calendar.MILLISECOND, 0);
			Date yearBeginDate = yearCalendarEnd.getTime();
			paramBean.setYearBeginDate(yearBeginDate);

			Date endDateAddOne = DateUtils.addDays(endDate, 1);
			paramBean.setEndDateAddOne(endDateAddOne);
			// paramBean.setEndDate(null);

			calendar2= Calendar.getInstance();
			logger.info("执行：selectReportList开始时间："+dateFormat.format(calendar2.getTime()));
			// 查询报表
			List<ReportAttendanceBean> reportList = reportExtDao.selectReportList(paramBean, employeeIds);
			calendar2= Calendar.getInstance();
			logger.info("执行：selectReportList结束时间："+dateFormat.format(calendar2.getTime()));
			
			calendar2= Calendar.getInstance();
			logger.info("执行：selectReportNowFixedList开始时间："+dateFormat.format(calendar2.getTime()));
			// 查询员工固定班次-应出勤天数
			List<ReportAttendanceBean> reportNowFixedList = reportExtDao.selectReportNowFixedList(paramBean,
					employeeIds);
			calendar2= Calendar.getInstance();
			logger.info("执行：selectReportNowFixedList结束时间："+dateFormat.format(calendar2.getTime()));
			
			calendar2= Calendar.getInstance();
			logger.info("执行：selectReportIrregularList开始时间："+dateFormat.format(calendar2.getTime()));
			// 查询员工无规律班次-应出勤天数
			List<ReportAttendanceBean> reportIrregularList = reportExtDao.selectReportIrregularList(paramBean,
					employeeIds);
			calendar2= Calendar.getInstance();
			logger.info("执行：selectReportIrregularList结束时间："+dateFormat.format(calendar2.getTime()));

			// 查询人员
			EmployeeExample employeeExample = new EmployeeExample();
			employeeExample.createCriteria().andEmployeeIdIn(employeeIds);
			List<Employee> employeeList = employeeDao.selectByExample(employeeExample);
			Map<Integer, Employee> employeeMap = new HashMap<Integer, Employee>();
			for (int ei = 0; ei < employeeList.size(); ei++) {
				employeeMap.put(employeeList.get(ei).getEmployeeId(), employeeList.get(ei));
			}

			// 年假查询参数
			RestVacationBean restVacationBean = new RestVacationBean();
			restVacationBean.setFurloughType(1);
			restVacationBean.setStartDate(paramBean.getBeginDate());

			// 取年份
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(restVacationBean.getStartDate());
			int thatYear = calendar.get(Calendar.YEAR);
			int thatmonth = calendar.get(Calendar.MONTH) +1;
			int lastYear = thatYear - 1;

			// 年假
			FurloughBalanceExample furloughBalanceExample = new FurloughBalanceExample();
			furloughBalanceExample.createCriteria().andEmployeeIdIn(employeeIds).andFurloughBalanceTypeEqualTo(1)
					.andYearEqualTo(Integer.toString(thatYear));
			List<FurloughBalance> fList = furloughBalanceDao.selectByExample(furloughBalanceExample);

			// 去年
			FurloughBalanceExample furloughBalanceExample2 = new FurloughBalanceExample();
			furloughBalanceExample2.createCriteria().andEmployeeIdIn(employeeIds).andFurloughBalanceTypeEqualTo(1)
					.andYearEqualTo(Integer.toString(lastYear));
			List<FurloughBalance> lastFList = furloughBalanceDao.selectByExample(furloughBalanceExample2);

			// 查询当天年假申请
			RequestExample requestExample = new RequestExample();
			requestExample.createCriteria().andEmployeeIdIn(employeeIds).andRequestTypeEqualTo(1)
					.andReportYearEqualTo(thatYear).andApprovalStateEqualTo(1);
			List<Request> rList = requestDao.selectByExample(requestExample);

			Map<Integer, List<Request>> thatYearRequestMap = new HashMap<Integer, List<Request>>();
			for (int ri = 0; ri < rList.size(); ri++) {
				if (thatYearRequestMap.containsKey(rList.get(ri).getEmployeeId())) {
					List<Request> eList = thatYearRequestMap.get(rList.get(ri).getEmployeeId());
					eList.add(rList.get(ri));
					thatYearRequestMap.put(rList.get(ri).getEmployeeId(), eList);
				} else {
					List<Request> eList = new ArrayList<Request>();
					eList.add(rList.get(ri));
					thatYearRequestMap.put(rList.get(ri).getEmployeeId(), eList);
				}
			}

			// 在申请中的去年年假时长
			RequestExample requestExample2 = new RequestExample();
			requestExample2.createCriteria().andEmployeeIdIn(employeeIds).andRequestTypeEqualTo(1)
					.andReportYearEqualTo(lastYear).andApprovalStateEqualTo(1);
			List<Request> rLastList = requestDao.selectByExample(requestExample2);

			// 获取默认员工班次
			EmployeeSchedulExample employeeSchedulExample=new EmployeeSchedulExample();
			employeeSchedulExample.createCriteria().andEmployeeIdIn(employeeIds).andSwIdEqualTo(1);
			List<EmployeeSchedul> esDefaultList=employeeSchedulDao.selectByExample(employeeSchedulExample);
			
			// 获取无规律班次
			employeeSchedulExample=new EmployeeSchedulExample();
			employeeSchedulExample.createCriteria().andEmployeeIdIn(employeeIds).andSwIdNotEqualTo(1);
			employeeSchedulExample.setOrderByClause("from_date desc");
			List<EmployeeSchedul> esIrregularList=employeeSchedulDao.selectByExample(employeeSchedulExample);
			
			Map<Integer, List<Request>> lastYearRequestMap = new HashMap<Integer, List<Request>>();
			for (int lyi = 0; lyi < rLastList.size(); lyi++) {
				if (lastYearRequestMap.containsKey(rLastList.get(lyi).getEmployeeId())) {
					List<Request> eList = lastYearRequestMap.get(rLastList.get(lyi).getEmployeeId());
					eList.add(rLastList.get(lyi));
					lastYearRequestMap.put(rLastList.get(lyi).getEmployeeId(), eList);
				} else {
					List<Request> eList = new ArrayList<Request>();
					eList.add(rLastList.get(lyi));
					lastYearRequestMap.put(rLastList.get(lyi).getEmployeeId(), eList);
				}
			}

			// 把统计信息放入报表对象中
			for (int i = 0; i < reportInfoList.size(); i++) {
				ReportAttendanceBean reportAttendanceBean = reportInfoList.get(i);
				Integer employeeId = reportAttendanceBean.getEmployeeId();
				for (int j = 0; j < reportList.size(); j++) {
					ReportAttendanceBean rab = reportList.get(j);
					if (rab.getMapEmployeeId().equals(employeeId)) {
						/** 因员工存在多班次问题，需要处理员工应出勤天数 **/
						// 获取员工固定班次数量
						List<ReportAttendanceBean> rNowFixedDayList = new ArrayList<ReportAttendanceBean>();
						if (reportNowFixedList.size() > 0) {
							rNowFixedDayList = reportNowFixedList.stream()
									.filter(s -> s.getMapEmployeeId().equals(employeeId)).collect(Collectors.toList());
						}
						// 获取员工无规律班次数量
						List<ReportAttendanceBean> rIrregularDayList = new ArrayList<ReportAttendanceBean>();
						if (reportIrregularList.size() > 0) {
							rIrregularDayList = reportIrregularList.stream()
									.filter(s -> s.getMapEmployeeId().equals(employeeId)).collect(Collectors.toList());
						}
						// 处理固定班次应出勤天数
						if (rNowFixedDayList.size() > 0) {
							if(rNowFixedDayList.get(0).getRealAttendanceDays()>0) {
								rab.setRealAttendanceDays(rNowFixedDayList.get(0).getRealAttendanceDays());
								// 处理无规律班次应出勤天数
								if (rIrregularDayList.size() > 0) {
									// 因员工当月会出现固定班次和无规律班次叠加出现，所以需要出勤天数相加
									rab.setRealAttendanceDays(rab.getRealAttendanceDays() + rIrregularDayList.get(0).getRealAttendanceDays());
									// 获取默认班次
									List<EmployeeSchedul> esdList=esDefaultList.stream().filter(s -> s.getEmployeeId().equals(employeeId)).collect(Collectors.toList());
									// 获取无规律班次
									List<EmployeeSchedul> esiList=esIrregularList.stream().filter(s -> s.getEmployeeId().equals(employeeId)).collect(Collectors.toList());
									if(esiList.size()>0) {
										EmployeeSchedul esEnd=esiList.get(esiList.size()-1);
										EmployeeSchedul esStart=esiList.get(0);
										if(esdList.size()>0) {
											EmployeeSchedul esd=esdList.get(0);
											if(esd.getFromDate().equals(esEnd.getFromDate()) 
													&& esd.getThruDate().equals(esStart.getThruDate())) {
												// 重新设置应出勤天数
												rab.setRealAttendanceDays(rIrregularDayList.get(0).getRealAttendanceDays());
											}
										}
										// 判断查询日期是否存在
										List<EmployeeSchedul> faList=esiList.stream().filter(s -> s.getFromDate().equals(paramBean.getBeginDate())).collect(Collectors.toList());
										if(faList.size() <= 0) {
											// 重新设置应出勤天数
											rab.setRealAttendanceDays(rIrregularDayList.get(0).getRealAttendanceDays());
										}
									}
								}
							}
						} else {
							// 如果全月为无规律班次时，设置应出勤天数
							if (rIrregularDayList.size() > 0) {
								if(rIrregularDayList.get(0).getRealAttendanceDays() > 0) {
									rab.setRealAttendanceDays(rIrregularDayList.get(0).getRealAttendanceDays());
								}
							}
						}
						/****/

						// 员工应出勤天数(应出勤天数=当月排班+法定假-产假（按排班休的产假）)
						if (rab.getRestBornUsed() != null || rab.getRestBornAttendUsed() != null) {
							int restBornUsed = 0;// 产假天数
							int restBornAttendUsed = 0;// 陪护假天数
							if (rab.getRestBornUsed() != null) {
								restBornUsed = rab.getRestBornUsed();
							}
							if (rab.getRestBornAttendUsed() != null) {
								restBornAttendUsed = rab.getRestBornAttendUsed();
							}
							reportInfoList.get(i).setRealAttendanceDays(
									rab.getRealAttendanceDays() - restBornUsed - restBornAttendUsed);
							
							// TODO 临时调整
							if(thatYear == 2021 && thatmonth == 2) {
								if(rab.getMapEmployeeId().intValue() == 3284) {
									reportInfoList.get(i).setRealAttendanceDays(5);
								}
							}
							
							// 判断是否为负数
							if(reportInfoList.get(i).getRealAttendanceDays()<0) {
								reportInfoList.get(i).setRealAttendanceDays(0);
								// 如果为负数，表示应出勤天数存在法定节假日
								//rab.setRestBornUsed(rab.getRestBornUsed());
								//rab.setYearRestBornUsed(rab.getRestBornAttendUsed());				
							}
						} else {
							reportInfoList.get(i).setRealAttendanceDays(rab.getRealAttendanceDays());
						}
						// 员工迟到次数
						reportInfoList.get(i).setLateCount(rab.getLateCount());
						// 员工早退次数
						reportInfoList.get(i).setLeaveEarlyCount(rab.getLeaveEarlyCount());
						// 员工旷工次数
						reportInfoList.get(i).setAbsentCount(rab.getAbsentCount());
						// 员工补签次数
						reportInfoList.get(i).setRetroactiveCount(rab.getRetroactiveCount());
						// 员工平日加班天数
						// Float value = (float)(Math.round((rab.getOvertimeNomal()/60/8)*100))/100;
						reportInfoList.get(i).setOvertimeNomal(this.minsToDays(rab.getOvertimeNomal()));
						// 员工双休日加班天数
						reportInfoList.get(i).setOvertimeWeekend(this.minsToDays(rab.getOvertimeWeekend()));
						// 员工节假日加班天数
						reportInfoList.get(i).setOvertimeHoliday(this.minsToDays(rab.getOvertimeHoliday()));
						// 员工请年假天数
						reportInfoList.get(i).setRestYearUsed(this.minsToDays(rab.getRestYearUsed()));
						// 员工请假调休天数
						reportInfoList.get(i).setRestTuneUsed(this.minsToDays(rab.getRestTuneUsed()));
						// 员工请产假天数(按筛选日期统计)
						if(rab.getRestBornUsed() != null) {
							if(rab.getRestBornUsed() > rab.getRealAttendanceDays()) {
								reportInfoList.get(i).setRestBornUsed(rab.getRealAttendanceDays());
							}else {
								reportInfoList.get(i).setRestBornUsed(rab.getRestBornUsed());
							}
						}
						// 员工请产检假天数
						reportInfoList.get(i).setRestCheckUsed(this.minsToDays(rab.getRestCheckUsed()));
						// 员工请丧假天数
						reportInfoList.get(i).setRestDieUsed(rab.getRestDieUsed());
						// 员工请婚假天数
						reportInfoList.get(i).setRestMarryUsed(rab.getRestMarryUsed());
						// 员工请陪产假天数
						reportInfoList.get(i).setRestBornAttendUsed(rab.getRestBornAttendUsed());
						// 员工请哺乳假天数
						reportInfoList.get(i).setRestSuckleUsed(this.minsToDays(rab.getRestSuckleUsed()));
						// 员工请病假天数
						reportInfoList.get(i).setRestIllUsed(this.minsToDays(rab.getRestIllUsed()));
						if(reportInfoList.get(i).getRestIllUsed() != null) {
							if(reportInfoList.get(i).getRestIllUsed() > rab.getRealAttendanceDays()) {
								reportInfoList.get(i).setRestIllUsed(Float.parseFloat(rab.getRealAttendanceDays()+""));
							}
						}
						// 员工请事假天数
						reportInfoList.get(i).setRestThingUsed(this.minsToDays(rab.getRestThingUsed()));
						// 当年考勤统计
						// 员工迟到次数累计
						reportInfoList.get(i).setYearLateCount(rab.getYearLateCount());
						// 员工早退次数
						reportInfoList.get(i).setYearLeaveEarlyCount(rab.getYearLeaveEarlyCount());
						// 员工旷工次数
						reportInfoList.get(i).setYearAbsentCount(rab.getYearAbsentCount());
						// 员工平日加班天数
						reportInfoList.get(i).setYearOvertimeNomal(this.minsToDays(rab.getYearOvertimeNomal()));
						// 员工双休日加班天数
						reportInfoList.get(i).setYearOvertimeWeekend(this.minsToDays(rab.getYearOvertimeWeekend()));
						// 员工节假日加班天数
						reportInfoList.get(i).setYearOvertimeHoliday(this.minsToDays(rab.getYearOvertimeHoliday()));
						// 年假开始日期
						reportInfoList.get(i).setYearRestYearBegin(rab.getYearRestYearBegin());

						// 年假
						RestVacationBean newRestVacationBean = this.getLastYearYearFurlough(restVacationBean,
								employeeId, systemConfigureList, employeeMap, fList, lastFList, thatYearRequestMap,
								lastYearRequestMap);

						// 可享受年假
						// reportInfoList.get(i).setYearRestYearAll(newRestVacationBean.getTotalVacation().divide(new
						// BigDecimal(60*8), 2, BigDecimal.ROUND_HALF_UP).floatValue());
						reportInfoList.get(i).setYearRestYearAll(newRestVacationBean.getTotalVacation()
								.divide(new BigDecimal(60 * 8), 0, BigDecimal.ROUND_DOWN).floatValue());
						
						// 判断年假大于0
						if(reportInfoList.get(i).getYearRestYearAll()!=null &&
								reportInfoList.get(i).getYearRestYearAll()> 0) {
							newRestVacationBean.setTotalVacation(new BigDecimal(reportInfoList.get(i).getYearRestYearAll().intValue()).
									multiply(new BigDecimal(8))
									.multiply(new BigDecimal(60)));
						}
						
						// 员工请年假天数
						/*
						 * reportInfoList.get(i)
						 * .setYearRestYearUsed((newRestVacationBean.getTotalVacation()
						 * .subtract(newRestVacationBean.getRealRestVacation())) .divide(new
						 * BigDecimal(60 * 8), 2, BigDecimal.ROUND_HALF_UP) .floatValue());
						 */
						if(newRestVacationBean.getRealRestVacation().compareTo(BigDecimal.ZERO) > 0) {
							// 员工请年假天数
							reportInfoList.get(i)
									.setYearRestYearUsed((newRestVacationBean.getTotalVacation()
											.subtract(newRestVacationBean.getRealRestVacation()))
													.divide(new BigDecimal(60 * 8), 2, BigDecimal.ROUND_HALF_UP)
													.floatValue());
						}else {
							// 员工请年假天数
							reportInfoList.get(i)
									.setYearRestYearUsed(newRestVacationBean.getTotalVacation()
													.divide(new BigDecimal(60 * 8), 0, BigDecimal.ROUND_DOWN)
													.floatValue());
						}
						
						// 剩余年假
						reportInfoList.get(i).setRestYearRemain(newRestVacationBean.getRealRestVacation()
								.divide(new BigDecimal(60 * 8), 2, BigDecimal.ROUND_HALF_UP).floatValue());
						
						// 判断请年假天数为负数，并且剩余年假大于可享受年假
						if(reportInfoList.get(i).getYearRestYearUsed() <= 0
								&& reportInfoList.get(i).getRestYearRemain() > reportInfoList.get(i).getYearRestYearAll()) {
							// 将剩余年假设置为可享受年假
							reportInfoList.get(i).setRestYearRemain(reportInfoList.get(i).getYearRestYearAll());
						}
						
						// 判断可享受年假为0
						if(reportInfoList.get(i).getYearRestYearAll() <= 0) {
							reportInfoList.get(i).setYearRestYearUsed(Float.parseFloat("0"));
							reportInfoList.get(i).setRestYearRemain(Float.parseFloat("0"));
						}
						
						// 判断员工请年假天数为负数
						if(reportInfoList.get(i).getYearRestYearUsed() <0) {
							reportInfoList.get(i).setYearRestYearUsed(Float.parseFloat("0"));
						}

						// 判断月份超出截止年份时，去年年假不设置
						if (yearFurloughList.size() > 0) {
							// 去年可享受年假天数
							reportInfoList.get(i).setYearRestLastYearAll(newRestVacationBean.getLastYearTotalVacation()
									.divide(new BigDecimal(60 * 8), 0, BigDecimal.ROUND_DOWN).floatValue());
							// 员工请去年年假天数
							reportInfoList.get(i)
									.setYearRestLastYearUsed((newRestVacationBean.getLastYearTotalVacation()
											.subtract(newRestVacationBean.getRealLastYearRestVacation()))
													.divide(new BigDecimal(60 * 8), 0, BigDecimal.ROUND_DOWN)
													.floatValue());
						} else {
							// 去年可享受年假天数
							reportInfoList.get(i).setYearRestLastYearAll(Float.parseFloat("0"));
							// 员工请去年年假天数
							reportInfoList.get(i).setYearRestLastYearUsed(Float.parseFloat("0"));
						}

						// 员工请假调休天数
						reportInfoList.get(i).setYearRestTuneUsed(this.minsToDays(rab.getYearRestTuneUsed()));
						// 剩余调休假
						reportInfoList.get(i).setYearRestTuneRemain(this.minsToDays(rab.getYearRestTuneRemain()));
						// 员工请病假天数
						reportInfoList.get(i).setYearRestIllUsed(this.minsToDays(rab.getYearRestIllUsed()));
						// 员工请事假天数
						reportInfoList.get(i).setYearRestThingUsed(this.minsToDays(rab.getYearRestThingUsed()));
						// 员工请产检假天数
						reportInfoList.get(i).setYearRestCheckUsed(this.minsToDays(rab.getYearRestCheckUsed()));
						// 可休产假(年)
						reportInfoList.get(i).setYearRestBorn(rab.getYearRestBorn());
						// 员工已休产假天数(年)
						reportInfoList.get(i).setYearRestBornUsed(rab.getYearRestBornUsed());
						// TODO 剩余产假(年)
						reportInfoList.get(i).setYearRestBornRemain(rab.getYearRestBornRemain());
						// 员工请哺乳假天数
						reportInfoList.get(i).setYearRestSuckleUsed(this.minsToDays(rab.getYearRestSuckleUsed()));
						// 员工请婚假天数
						reportInfoList.get(i).setYearRestMarryUsed(rab.getYearRestMarryUsed());
						// 员工请丧假天数
						reportInfoList.get(i).setYearRestDieUsed(rab.getYearRestDieUsed());
						// 员工请陪产假天数
						reportInfoList.get(i).setYearRestBornAttendUsed(rab.getYearRestBornAttendUsed());

						// 备注
						String description = "";
						if (rab.getRestCount() != null) {
							description = description + " 调休：" + rab.getRestCount() + "条";
						}
						if (rab.getAnnualLeaveCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 年假：" + rab.getAnnualLeaveCount() + "条";
						}
						if (rab.getMarriageCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 婚假：" + rab.getMarriageCount() + "条";
						}
						if (rab.getBereavementCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 丧假：" + rab.getBereavementCount() + "条";
						}
						if (rab.getMatterCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 事假：" + rab.getMatterCount() + "条";
						}
						if (rab.getSickCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 病假：" + rab.getSickCount() + "条";
						}
						if (rab.getTripCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 出差：" + rab.getTripCount() + "条";
						}
						if (rab.getOutCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 外出：" + rab.getOutCount() + "条";
						}
						if (rab.getLactationCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 哺乳假 ：" + rab.getLactationCount() + "条";
						}
						if (rab.getEscortCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 陪护假 ：" + rab.getEscortCount() + "条";
						}
						if (rab.getAntenatalCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 产检假：" + rab.getAntenatalCount() + "条";
						}
						if (rab.getMaternityCount() != null) {
							if (description != "") {
								description = description + "<br>";
							}
							description = description + " 产假：" + rab.getMaternityCount() + "条";
						}
						if (description != "") {
							String str = "存在未审批申请：<br>" + description;
							description = str;
						}
						reportInfoList.get(i).setDescription(description);
					}
				}
			}
			count = reportExtDao.countByParam(paramBean);
		}

		ReportAttendancePageBean reportAttendancePageBean = new ReportAttendancePageBean();
		reportAttendancePageBean.setReportInfoList(reportInfoList);
		reportAttendancePageBean.setPageTotal(count);
		return reportAttendancePageBean;
	}

	/**
	 * 分钟数转换成day，保留两位小数（除以60*8）
	 * 
	 * @param mins
	 * @return 天数
	 */
	private Float minsToDays(Float mins) {
		if (mins != null) {
			return (float) (Math.round((mins / 60 / 8) * 100)) / 100;
		} else {
			return null;
		}
		// Float days = (float)(Math.round((hours/60/8)*100))/100;
	}

	/**
	 * 在1,2月份查询去年和今年的年假余额
	 */
	@Override
	public RestVacationBean getLastYearYearFurlough(RestVacationBean restVacationBean, Integer employeeId,
			List<SystemConfigure> systemConfigureList, Map<Integer, Employee> employeeMap, List<FurloughBalance> fList,
			List<FurloughBalance> lastFList, Map<Integer, List<Request>> thatYearRequestMap,
			Map<Integer, List<Request>> lastYearRequestMap) {

		RestVacationBean newRestVacationBean = new RestVacationBean();
		// 取年份
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(restVacationBean.getStartDate());
		int year = calendar.get(Calendar.YEAR);
		int lastYear = year - 1;
		newRestVacationBean.setThisYear(year);
		newRestVacationBean.setLastYear(lastYear);
		// 年初、年末时间
		Calendar calendarBegin = Calendar.getInstance();
		calendarBegin.setTime(restVacationBean.getStartDate());
		calendarBegin.set(Calendar.MONTH, 0);
		calendarBegin.set(Calendar.DAY_OF_MONTH, 1);
		calendarBegin.set(Calendar.HOUR_OF_DAY, 0);
		calendarBegin.set(Calendar.MINUTE, 0);
		calendarBegin.set(Calendar.SECOND, 0);
		calendarBegin.set(Calendar.MILLISECOND, 0);
		Date beginDate = calendarBegin.getTime();
		// 去年的开始时间、结束时间
		Calendar lastCalendarBegin = Calendar.getInstance();
		lastCalendarBegin.setTime(beginDate);
		lastCalendarBegin.add(Calendar.YEAR, -1);
		Date lastBeginDate = lastCalendarBegin.getTime();

		/*
		 * 年假
		 */
		newRestVacationBean.setFurloughType(1);

		// 查询某人的当年年假（分钟数）
		// Employee employee = employeeDao.selectByPrimaryKey(employeeId);

		BigDecimal yearFurlough = new BigDecimal(0);
		BigDecimal lastYearFurlough = new BigDecimal(0);

		Employee employee = employeeMap.get(employeeId);
		if (employee.getFirstDate() != null && employee.getEntryDate() != null) {
			Float yearFurloughFloat = YearFurloughUtils.getYearFurloughHours(employee.getFirstDate(),
					employee.getEntryDate(), restVacationBean.getStartDate(), systemConfigureList) * 8 * 60;
			yearFurloughFloat = (float) Math.round(yearFurloughFloat);
			// 去年年假，分钟数
			Float lastYearFurloughFloat = YearFurloughUtils.getYearFurloughHours(employee.getFirstDate(),
					employee.getEntryDate(), lastBeginDate, systemConfigureList) * 8 * 60;
			lastYearFurloughFloat = (float) Math.round(lastYearFurloughFloat);

			yearFurlough = new BigDecimal(yearFurloughFloat.toString());
			lastYearFurlough = new BigDecimal(lastYearFurloughFloat.toString());
		}

		// 年假
		/*
		 * FurloughBalanceExample furloughBalanceExample=new FurloughBalanceExample();
		 * furloughBalanceExample.createCriteria() .andEmployeeIdEqualTo(employeeId)
		 * .andFurloughBalanceTypeEqualTo(1) .andYearEqualTo(Integer.toString(year));
		 * List<FurloughBalance>
		 * fList=furloughBalanceDao.selectByExample(furloughBalanceExample);
		 */
		// 去年
		/*
		 * FurloughBalanceExample furloughBalanceExample2=new FurloughBalanceExample();
		 * furloughBalanceExample2.createCriteria() .andEmployeeIdEqualTo(employeeId)
		 * .andFurloughBalanceTypeEqualTo(1)
		 * .andYearEqualTo(Integer.toString(lastYear)); List<FurloughBalance>
		 * lastFList=furloughBalanceDao.selectByExample(furloughBalanceExample2);
		 */

		// 在申请中的年假时长
		BigDecimal usingYearFurlough = new BigDecimal(0);
		/*
		 * RequestExample requestExample=new RequestExample();
		 * requestExample.createCriteria().andEmployeeIdEqualTo(employeeId)
		 * .andRequestTypeEqualTo(1) .andReportYearEqualTo(year)
		 * .andApprovalStateEqualTo(1); List<Request>
		 * rList=requestDao.selectByExample(requestExample);
		 */
		List<Request> rList = thatYearRequestMap.get(employeeId);
		// if (rList.size()>0) {
		if (rList != null) {
			for (Request request : rList) {
				usingYearFurlough = usingYearFurlough.add(request.getHours());
			}
		}

		// 在申请中的去年年假时长
		BigDecimal usingLastYearFurlough = new BigDecimal(0);
		/*
		 * RequestExample requestExample2=new RequestExample();
		 * requestExample2.createCriteria().andEmployeeIdEqualTo(employeeId)
		 * .andRequestTypeEqualTo(1) .andReportYearEqualTo(lastYear)
		 * .andApprovalStateEqualTo(1); List<Request>
		 * rLastList=requestDao.selectByExample(requestExample2);
		 */
		List<Request> rLastList = lastYearRequestMap.get(employeeId);
		// if (rLastList.size()>0) {
		if (rLastList != null) {
			for (Request request : rLastList) {
				usingLastYearFurlough = usingLastYearFurlough.add(request.getHours());
			}
		}

		// 循环当年，年假剩余
		FurloughBalance furloughBalance = null;
		for (int fi = 0; fi < fList.size(); fi++) {
			if (fList.get(fi).getEmployeeId().equals(employeeId)) {
				furloughBalance = fList.get(fi);
				break;
			}
		}
		// 余额表没有数据时
		// if (fList.size()==0) {
		if (furloughBalance == null) {
			newRestVacationBean.setUsedVacation(usingYearFurlough);
			newRestVacationBean.setRestVacation(yearFurlough.subtract(usingYearFurlough));
			newRestVacationBean.setTotalVacation(yearFurlough);
			newRestVacationBean.setRealRestVacation(yearFurlough);
		} else {
			// BigDecimal restYearFurlough=fList.get(0).getBalanceHoursDay();
			BigDecimal restYearFurlough = furloughBalance.getBalanceHoursDay();
			newRestVacationBean.setUsedVacation(yearFurlough.subtract((restYearFurlough).subtract(usingYearFurlough)));
			newRestVacationBean.setRestVacation(restYearFurlough.subtract(usingYearFurlough));
			newRestVacationBean.setTotalVacation(yearFurlough);
			newRestVacationBean.setRealRestVacation(restYearFurlough);
		}

		// 循环去年，年假剩余
		FurloughBalance lastFurloughBalance = null;
		for (int li = 0; li < lastFList.size(); li++) {
			if (lastFList.get(li).getEmployeeId().equals(employeeId)) {
				lastFurloughBalance = lastFList.get(li);
				break;
			}
		}
		// 去年的年假
		// if (lastFList.size()==0) {//余额表没有数据时
		if (lastFurloughBalance == null) {
			newRestVacationBean.setLastYearUsedVacation(usingLastYearFurlough);
			newRestVacationBean.setLastYearRestVacation(lastYearFurlough.subtract(usingLastYearFurlough));
			newRestVacationBean.setLastYearTotalVacation(lastYearFurlough);
			newRestVacationBean.setRealLastYearRestVacation(lastYearFurlough);
		} else {
			// BigDecimal restLastYearFurlough=lastFList.get(0).getBalanceHoursDay();
			BigDecimal restLastYearFurlough = lastFurloughBalance.getBalanceHoursDay();
			newRestVacationBean.setLastYearUsedVacation(
					lastYearFurlough.subtract(restLastYearFurlough).subtract(usingLastYearFurlough));
			newRestVacationBean.setLastYearRestVacation(restLastYearFurlough.subtract(usingLastYearFurlough));
			newRestVacationBean.setLastYearTotalVacation(lastYearFurlough);
			newRestVacationBean.setRealLastYearRestVacation(restLastYearFurlough);
		}
		return newRestVacationBean;
	}
}
